<?php


class Captcha{
    private $width;     //验证码的宽
    private $height;    //验证码的高
    private $fontfile;  //字体文件
    private static $instance;  //保存实例化对象
    private $num;  //保存实例化对象
    private $str;  //生成的随机字符
    private static $img;  //图片资源对象

    private function __construct($width, $height,$fontfile, $num){
        $this->init($width, $height,$fontfile, $num);

    }

    /**
     * 初始化参数
     */
    private function init($width, $height,$fontfile, $num){
        $this->width = $width;
        $this->height = $height;
        $this->fontfile = $fontfile;
        $this->num = $num;
    }

    private function __clone(){}    //防止克隆

    public static function getInstance($width, $height,$fontfile, $num){
        if(!self::$instance instanceof self){
            return self::$instance = new self($width, $height,$fontfile, $num);
        }
        return self::$instance;
    }

    //生成随机字符
    private function randomStr(){
        //生成A-Z a-z 0-9的字符串
        $str = implode('', array_merge(range('A', 'Z'), range('a', 'z'), range(0,9)));
        $len = strlen($str);    //获取字符串的长度
        $ran = rand(1, $len);   //随机生成一个数 在 1 - 该字符串的长度之内

        for($i = 0; $i<$ran; $i++){     //随机循环次数 用来将字母变成大写
            $ran_in = rand(0, $ran);    //再随机生成一个数
            $str[$ran_in] = strtoupper($str[$ran_in]);  //将字母变成大写
        }
        // echo $str;
        $shuffle = str_shuffle($str);//随机打乱字符串
        $this->str = substr($shuffle, 0, $this->num);//截取前几个
    }

    //创建一个图片
    public function showImg(){
        // 1.创建真彩图片
        self::$img = imagecreatetruecolor($this->width, $this->height);
//        var_dump(self::$img);die;

        $white = imagecolorallocate(self::$img, 255, 255, 255);//2.背景色

        //$text_color = imagecolorallocate(self::$img, 255, 0, 0);//文字颜色

        // 3.在指定图片画矩形
        imagefilledrectangle(self::$img, 0, 0, $this->width, $this->height, $white);

        $this->randomStr();
        $this->insertToImg();
        $this->point();
        $this->line();

        ob_clean();
        header("Content-Type:image/jpeg");
        imagejpeg(self::$img);
    }

    //将随机生成的字符插入图片中
    private function insertToImg(){
        $fontsize = 30;
        for($i=0;$i<strlen($this->str);$i++){

            $color = imagecolorallocate(self::$img,rand(0,255),rand(0,255),rand(0,255));

            //定义字符Y坐标
            $y= ($this->height+30)/2 + rand(-1,1);

            //定义字符X坐标
            $x = $i*30+8;

            imagettftext(self::$img, $fontsize, rand(-30,30),$x,$y,$color,realpath($this->fontfile),$this->str[$i]);
        }
        session_start();
        $_SESSION['captcha'] = strtolower($this->str);
    }

    //生成雪花点
    private function point(){

        //6. 防止别人去恶意刷我们的验证码 可以在这个图片上面加上一些点 imagesetpixel()
        for($i=0;$i<50;$i++){
            $potcolor = imagecolorallocate(self::$img,rand(0,255),rand(0,255),rand(0,255));
            //imagesetpixel(self::$img,rand(0,$width),rand(0,$height),$potcolor);

            //原点
            imagefilledellipse(self::$img,rand(0,$this->width),rand(0,$this->height),rand(1,3),rand(1,3),$potcolor);
        }
    }

    //生成线
    private function line(){
        for($i=0;$i<5;$i++) {
            $linecolor = imagecolorallocate(self::$img, rand(0, 255), rand(0, 255), rand(0, 255));

            imageline(self::$img,rand(0,$this->width),rand(0,$this->height),rand($this->width,$this->width),rand(0,$this->height),$linecolor);
        }
    }

    function __destruct(){
        imagedestroy(self::$img);
    }

}

$captcha = Captcha::getInstance(150, 50, '../fonts/STLITI.TTF', 4);
$captcha->showImg();

//生成验证码
//function captcha($width='150', $height='50'){
//
//    // 1.创建真彩图片
//    $img = imagecreatetruecolor($width, $height);
//
//    $white = imagecolorallocate($img, 255, 255, 255);//2.背景色
//
//    $text_color = imagecolorallocate($img, 255, 0, 0);//文字颜色
//
//    // 3.在指定图片画矩形
//    imagefilledrectangle($img, 0, 0, $width, $height, $white);
//
//    //4.将随机数写到这个图片上
//    //定义字符Y坐标
//    $fontsize = 30;
//    $str = random_str();
//    for($i=0;$i<strlen($str);$i++){
//
//		$color = imagecolorallocate($img,rand(0,255),rand(0,255),rand(0,255));
//
//		//定义字符Y坐标
//		$y= ($height+30)/2 + rand(-1,1);
//
//		//定义字符X坐标
//		$x = $i*30+8;
//
//		imagettftext($img,$fontsize,rand(-30,30),$x,$y,$color,realpath('../fonts/texb.ttf'),$str[$i]);
//	}
//
//    // imagestring($img, 5, 0, 10, $str, $text_color);
//    // imagettftext($img, 20, rand(-30, 30), imagefontwidth(20), imagefontheight(20), $text_color, 'texb.ttf', $str);
//
//    //6. 防止别人去恶意刷我们的验证码 可以在这个图片上面加上一些点 imagesetpixel()
//	for($i=0;$i<50;$i++){
//		$potcolor = imagecolorallocate($img,rand(0,255),rand(0,255),rand(0,255));
//		//imagesetpixel($img,rand(0,$width),rand(0,$height),$potcolor);
//		//原点
//		imagefilledellipse($img,rand(0,$width),rand(0,$height),rand(1,3),rand(1,3),$potcolor);
//
//	}
//
//	//7.划线
//	for($i=0;$i<5;$i++) {
//		$linecolor = imagecolorallocate($img, rand(0, 255), rand(0, 255), rand(0, 255));
//
//		imageline($img,rand(0,$width),rand(0,$height),rand($width,$width),rand(0,$height),$linecolor);
//    }
//
//    // 8.保存到session
//    session_start();
//    $_SESSION['captcha'] = strtolower($str);
//
//    //输出
//    ob_clean();
//    header("Content-Type:image/jpeg");
//    imagejpeg($img);
//
//    imagedestroy($img);
//}
//
//captcha();